using System;
using System.Collections.Generic;
using System.Text;
using NBusiness.Query;

namespace NBusiness.Data.Providers.SqlServer.Query
{
    public class SqlTable : ITable
    {
        #region Member fields and properties

        private string _name;
        private string _alias;

        public string Name
        {
            get { return _name; }
        }

        public string Alias
        {
            get { return _alias; }
            set { _alias = value; }
        }

        #endregion

        #region Constructors
        public SqlTable(string name)
            : this(name, null)
        { }
        public SqlTable(string name, string alias)
        {
            _name = name;
            _alias = alias;
        }
        #endregion

        #region IRelationalElement Members

        public string ToSql()
        {
            return ToSql(new SqlQueryContext());
        }
        public string ToSql(IQueryContext context)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("[" + Name + "]");
            string alias = (context as SqlQueryContext).EnsureAlias(this);

            // Context may not assign an alias in an insert
            if (!string.IsNullOrEmpty(alias) && Name != alias)
                builder.Append(" AS [" + alias + "]");

            return builder.ToString();
        }

        #endregion

        #region Operator overloads
        public static SqlSelect operator &(SqlTable table, IExpression e)
        {
            return new SqlSelect().From(table).Where(e) as SqlSelect;
        } 
        #endregion

        #region ISelect Members
        public ISelect Where(IExpression expression)
        {
            return new SqlSelect().From(this).Where(expression);
        }

        public ISelect OrderBy(SortOrder order, params IColumn[] columns)
        {
            return new SqlSelect().From(this).OrderBy(order, columns);
        }

        public ISelect GroupBy(params IColumn[] groupBy)
        {
            return new SqlSelect().From(this).GroupBy(groupBy);
        }

        public ISelect Select(params ISelectable[] selectable)
        {
            return new SqlSelect().From(this).Select(selectable);
        }

        #endregion

        #region ITable Members

        public ITable As(string alias)
        {
            Alias = alias;
            return this;
        }

        public IColumn Column(string name)
        {
            return new SqlColumn(name, this);
        }
        #endregion

        #region Object overrides
        public override string ToString()
        {
            return "[" + Name + "]";
        }
        #endregion

        #region IJoinable Members

        public IFrom InnerJoin(IExpression on)
        {
            return new SqlJoin(this, on, SqlJoinType.Inner);
        }

        public IFrom OutterLeftJoin(IExpression on)
        {
            return new SqlJoin(this, on, SqlJoinType.OutterLeft);
        }

        public IFrom OutterRightJoin(IExpression on)
        {
            return new SqlJoin(this, on, SqlJoinType.OutterRight);
        }

        #endregion
    }
}
